package com.han.hotelplat.cms.controller.systemuser;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.han.hotelplat.comm.utils.MD5;
import com.han.hotelplat.pojo.systemuser.Permission;
import com.han.hotelplat.pojo.systemuser.Resource;
import com.han.hotelplat.pojo.systemuser.Role;
import com.han.hotelplat.pojo.systemuser.Systemuser;
import com.han.hotelplat.service.systemuser.SystemuserService;



public class ShiroDataBaseRealm extends AuthorizingRealm{
	@Autowired
	private SystemuserService systemuserService;
	
    public ShiroDataBaseRealm() {  
        setName("ShiroDataBaseRealm"); //This name must match the name in the User class's getPrincipals() method  
      //  setCredentialsMatcher(new Sha256CredentialsMatcher());  
        setCredentialsMatcher(new AllowAllCredentialsMatcher());  
    }  
    
    public void clearAuthz() {  
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPreviousPrincipals());
    }  
    
    /**
     * 
     * 当用户进行访问链接时的授权方法
     * 
     */
    @Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        if (principals == null) {
            throw new AuthorizationException("Principal对象不能为空");
        }
        
        Iterator its = principals.fromRealm(getName()).iterator();
        
        if (its.hasNext() == false) {
            throw new AuthorizationException("找不到User啊，怎么没有登录？");
        }
        
        Systemuser user = (Systemuser) its.next();
        //获取权限
        List<String> permissions = new ArrayList<String>();
        StringBuffer sb = new StringBuffer();
        if(null!=user.getVocation()
           &&user.getVocation().equals("admin")){//超级管理员做一个特权校验
        	List<Permission> perms = systemuserService.findAllPermissions();
        	for(Permission permission:perms){
        		String p = permission.getPermission();
        		permissions.add(p);
        		sb.append(p+";");
        	}
        	List<Resource> resourceList = systemuserService.findAllResource();
            for(Resource resource:resourceList){
            	permissions.add("resource:"+resource.getRestype()+":"+resource.getRelationid());
            	sb.append("resource:"+resource.getRestype()+":"+resource.getRelationid()+";");
            }
        }else{
        	//通过Role获取permission
            List<Permission> perms = new ArrayList<Permission>();
            for(Role role:user.getRoles()){
            	perms.addAll(role.getPermissions());
            }
            for(Permission permission:perms){
        		String p = permission.getPermission();
        		permissions.add(p);
        		sb.append(p+";");
        	}
            //通过Resource组合Shiro permission
            for(Resource resource:user.getResources()){
            	permissions.add("resource:"+resource.getRestype()+":"+resource.getRelationid());
            	sb.append("resource:"+resource.getRestype()+":"+resource.getRelationid()+";");
            }
        }
        
        //获取角色
        List<String> roles = new ArrayList<String>();
        String[] vs = user.getVocation().split(",");
        for(String s:vs){
        	roles.add(s);
        	sb.append(s+";");
        }
        
        //打印
        System.out.println("######## doGetAuthorizationInfo username="+user.getUsername()+" #########");
        System.out.println(sb);

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.addStringPermissions(permissions);
        info.addRoles(roles);
        return info;
    }

    /**
     * 用户登录的认证方法
     * 
     */
    @Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;

        String username = usernamePasswordToken.getUsername();
        
        if (username == null) {
            throw new AccountException("用户名不能为空");
        }

        Systemuser user = systemuserService.findUserByUsernam(username);

        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }
        
        String password = String.valueOf(usernamePasswordToken.getPassword());
        password = MD5.toMD5(password).toUpperCase();
        
        if(!user.getPassword().equals(password)){
        	 throw new AccountException("用户密码错误");
        }
        
        //修改时间
        user.setLastlogintime(new Date());
        systemuserService.update(user);
        
        return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
    }
}
